Abstract
En el presente notebook se encuentra el trabajo realizado en base a los precios que provienen de la aplicación de trading *Metratader 5* esto con la intención de realizar un profundo análisis que nos lleve a visualizar y comprender el funcionamiento de lo que un sistema de trading conlleva. De esta manera, podemos denotar las operaciones que un broker tiene que realizar, así como las acciones premeditadas que el individuo presenta para poder proceder con el ingreso monetario al trading hecho en cierto periodo de tiempo. Por otro lado, se hacen presentes las visualizaciones respectivas a lo que un Análisis Técnico representa.
En el presente laboratorio se muestra un análisis importante en base a un ingreso ficticio realizado a un sistema de trading creado desde cero con diversas decisiones de inversión tomadas respecto a lo que un Análisis Técnico refiere.
Recordemos que el análisis técnico es un sistema que permite examinar y predecir los movimientos de precios en los mercados financieros a partir de datos históricos y estadísticas de mercado. Se basa en la idea de que, si un inversor puede identificar patrones previos, entonces podrá predecir los movimientos futuros de los precios de manera bastante exacta.
Los analistas técnicos disponen de una gran variedad de herramientas para detectar tendencias y patrones en los gráficos. Entre ellas figuran las medias móviles, los niveles de soporte y resistencia o las bandas de Bollinger. Todas las herramientas comparten un mismo objetivo, que los inversores que usan el análisis técnico entiendan mejor los movimientos de los gráficos y puedan identificar las tendencias con mayor facilidad.
Una vez dicho lo anterior, se comienza realizando la programación de medias móviles y bandas de Bollinger dentro del sistema creado con el objetivo de establecer ciertos parámetros que definan los alcances del inversionista. Una vez que los parámetros de decisión y los alcances del inversionista se encuentran asentados, se procede a realizar una optimización, que es la parte más importante de este laboratorio, dado que con ella podremos justificar el principal alcance de nuestro inversionista y así poder visualizar mejores resultados para el mismo.
Continuando con el procedimiento se presentan diversas visualizaciones con el objetivo de tener la parte teórica y de programación de manera más didáctica, así como de observar los resultados obtenidos en conjunto con las conclusiones a las que se llegaron.
Este laboratorio tiene como propósito utilizar entre dos y cuatro estudios técnicos como herramientas para la generación de oportunidades de trading, utilizando criterios financieros que ayuden al establecimiento del sistema.
Aplicar el análisis técnico de manera efectiva.
Reconocer la importancia de los criterios financieros.
Aplicar los conocimientos de los aspectos financieros y estadísticos.
Para pode correr el presente notebook, será necesario haber instalado o ya tener el archivo requirements.txt que presenta lo siguiente:
Las dependencias necesarias para poder correr el notebook son:
%%capture
# Install all the pip packages in the requirements.txt
import sys
!{sys.executable} -m pip install -r requirements.txt
# Para que no aparezcan los warnings
import warnings
if not sys.warnoptions:
warnings.simplefilter("ignore")
from functions import *
En este apartado encontraremos la descarga de datos para el periodo de entrenamiento, dado que con dichos datos se creará el modelo de nuestro sistema de trading. Mostrando así la tabla con los datos tal cual provienen de Metatrader 5.
Como datos iniciales, se tiene que:
import MetaTrader5 as mt5
usuario = 'Daniel Garcia'
symbol = 'EURUSD'
meta_path = 'C:\Program Files\MetaTrader 5 Terminal\\terminal64.exe'
login_count = 5400339
password_count = '2qeDQrhu'
server_name = 'FxPro-MT5'
start_date_backtest = datetime.datetime(year=2018, month=1, day=1)
end_date_backtest = datetime.datetime(year=2018, month=12, day=31)
start_date_prueba = datetime.datetime(year=2019, month=1, day=1)
end_date_prueba = datetime.datetime(year=2019, month=12, day=31)
datos_train, datos_prueba = historicos(meta_path, login_count, password_count, server_name,
start_date_backtest, end_date_backtest, start_date_prueba,
end_date_prueba, symbol)
datos_train
| time | open | high | low | close | tick_volume | spread | real_volume | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2018-01-02 00:00:00 | 1.20087 | 1.20095 | 1.20007 | 1.20090 | 705 | 16 | 155200000 |
| 1 | 2018-01-02 00:15:00 | 1.20090 | 1.20094 | 1.20034 | 1.20058 | 1083 | 19 | 216600000 |
| 2 | 2018-01-02 00:30:00 | 1.20059 | 1.20160 | 1.20058 | 1.20135 | 969 | 18 | 193800000 |
| 3 | 2018-01-02 00:45:00 | 1.20135 | 1.20141 | 1.20125 | 1.20130 | 1234 | 20 | 246800000 |
| 4 | 2018-01-02 01:00:00 | 1.20130 | 1.20139 | 1.20019 | 1.20137 | 4787 | 18 | 957400000 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 24740 | 2018-12-31 05:00:00 | 1.14348 | 1.14360 | 1.14337 | 1.14338 | 2825 | 15 | 423750000 |
| 24741 | 2018-12-31 05:15:00 | 1.14338 | 1.14367 | 1.14337 | 1.14365 | 3115 | 15 | 467250000 |
| 24742 | 2018-12-31 05:30:00 | 1.14365 | 1.14392 | 1.14356 | 1.14392 | 3730 | 15 | 559500000 |
| 24743 | 2018-12-31 05:45:00 | 1.14392 | 1.14402 | 1.14363 | 1.14378 | 3675 | 15 | 551250000 |
| 24744 | 2018-12-31 06:00:00 | 1.14378 | 1.14389 | 1.14311 | 1.14321 | 5133 | 15 | 769950000 |
24745 rows × 8 columns
datos_prueba
| time | open | high | low | close | tick_volume | spread | real_volume | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2019-01-02 06:00:00 | 1.14450 | 1.14456 | 1.14431 | 1.14437 | 4375 | 15 | 656250000 |
| 1 | 2019-01-02 06:15:00 | 1.14437 | 1.14458 | 1.14431 | 1.14439 | 3462 | 15 | 519300000 |
| 2 | 2019-01-02 06:30:00 | 1.14439 | 1.14463 | 1.14421 | 1.14454 | 3953 | 15 | 592950000 |
| 3 | 2019-01-02 06:45:00 | 1.14454 | 1.14454 | 1.14437 | 1.14443 | 2893 | 15 | 433950000 |
| 4 | 2019-01-02 07:00:00 | 1.14443 | 1.14477 | 1.14443 | 1.14474 | 4092 | 15 | 613800000 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 24712 | 2019-12-31 05:00:00 | 1.12092 | 1.12093 | 1.12039 | 1.12050 | 3654 | 15 | 548100000 |
| 24713 | 2019-12-31 05:15:00 | 1.12050 | 1.12055 | 1.12026 | 1.12026 | 2456 | 15 | 368400000 |
| 24714 | 2019-12-31 05:30:00 | 1.12026 | 1.12028 | 1.11980 | 1.12026 | 2917 | 15 | 437550000 |
| 24715 | 2019-12-31 05:45:00 | 1.12026 | 1.12037 | 1.12023 | 1.12029 | 2232 | 15 | 334800000 |
| 24716 | 2019-12-31 06:00:00 | 1.12029 | 1.12037 | 1.12026 | 1.12036 | 2476 | 15 | 371400000 |
24717 rows × 8 columns
En estos DataFrames podemos observar la descarga de datos pertinentes a ambos periodos definidos en el inicio de este apartado. De modo que tenemos los datos divididos en train y prueba, tal como se muestran.
En el presente apartado se muestra cómo funciona el sistema de trading creado, los aspectos financieros y los aspectos estadísticos con los que cuenta y en base a los cuáles se toman las decisiones correspondientes. En este primer punto se visualizará toda la teoría a manera de introducción a lo que se esta realizando y posterior a ello, se muestran los resultados del periodo de entrenamiento donde se realizó el sistema y se hace el proceso correspondiente para la obtención de resultados. Como segundo paso, se realiza la optimización de ciertas variables con el objetivo de tener el mayor profit acumulado. Finalmente, se corroboran todos los resultados con el periodo de prueba que se indicó al inicio de este laboratorio.
Dentro de los criterios financieros encontramos:
Uso de datos: Se utilizaron datos provenientes de Metatrader 5, mismos que corresponden al periodo de prueba y de entrenamiento que el mismo laboratorio establecía.
Instrumento utilizado: En este caso se utilizó el EuroDólar, éstos son depósitos denominados en dólares estadounidenses que se mantienen en bancos fuera de los Estados Unidos, y por lo tanto no están bajo la jurisdicción de la Reserva Federal. En consecuencia, estos depósitos están sujetos a una menor regulación que depósitos similares en los Estados Unidos, lo que permite mayores márgenes de ganancia.
Granularidad: Para este laboratorio se utilizó una granularidad de 15 minutos, dado que al ser periodos largos la propia aplicación de Metatrader 5 tronaba al tener muchos datos por lo que la mejor decisión para solucionar el problema fue elegir la descarga de datos cada 15.
Validaciones históricas: Para este caso no se realizaron validaciones históricas porque se procedía con la realización del sistema de trading.
Las MAD utilizadas fueron:
Respecto a los estudios técnicos utilizados se realizaron dos:
Para este caso tenemos generaciones de señales de acuerdo al estudio técnico que se utilizó.
En el caso de Moving Average se presentan dos de éstas, una que es de corto plazo y otra a largo plazo. De esta manera se relizará una compra cuando la línea correspondiente al corto plazo cruce la de largo plazo de manera ascendente, es decir de abajo hacía arriba. En el caso de la señal de venta, ésta se realizará cuando la línea correspondiente al corto plazo cruce a la de largo de manera descendente, es decir de arriba hacía abajo.
En el caso de Bollinger Bands se realizará una compra cuando el precio de nuestro activo se encuentre por debajo de la línea inferior correspondiente a las propias bandas de Bollinger. Para el caso de la señal de venta, esta se realizará cuando el precio de nuestro activo en análisis se encuentre por encima de la línea superior correspondiente a las bandas.
Función de Utilidad: La función que se buscó optimizar fue la llamada "cost_function" en donde se realiza el sistema de trading, buscando la maximización del profit acumulado.
Parámetro a optimizar:
Nombre: Número de acciones
Descripción: Número de acciones utilizadas dentro de la inversión
Tipo de valor: numérico
Rango de valores: 100 - 10000
Tamaño de paso mínimo: partículas
Nombre: SL/TP
Descripción: Valores correspondientes al stop loss y take profit
Tipo de valor: numérico
Rango de valores: 0.01 - 0.06
Tamaño de paso mínimo: partículas
Nombre: Window
Descripción: Tamaño de ventana utilizado en los aspectos estadísticos
Tipo de valor: numérico
Rango de valores: 20 - 100
Tamaño de paso mínimo: partículas
Nombre: Desviación estándar
Descripción: Valor correspondiente a la desviación estándar que separan a las bandas de bollinger
Tipo de valor: numérico
Rango de valores: 0.05 - 4
Tamaño de paso mínimo: partículas
Espacio de búsqueda:
Tiempo de búsqueda exhaustiva: Al hacerlo en una búsqueda exhaustiva, que sería el optimizador heurístico. Se presentó un tiempo aproximado de 40 minutos.
Tiempo de búsqueda PSO: Al hacerlo con una optimización PSO, se presentó un tiempo aproximado de 18 minutos.
Método de optimización: Se utilizó PSO y una búsqueda exhaustiva para poder determinar la mejor combinación de los parámetros que se usaron y asismismo para verificarlos en los diferentes casos.
num_acciones = 100
pp_ma = 0.02
pg_ma = 0.02
w_bb = 100
sd_bb = 2
funcion_ma_bb = function(num_acciones, pp_ma, w_bb, sd_bb, 'backtest')
100 0.02 0.01 100 2
2021-11-30 00:55:23,887 - numexpr.utils - INFO - Note: NumExpr detected 16 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8. 2021-11-30 00:55:23,887 - numexpr.utils - INFO - NumExpr defaulting to 8 threads.
MAD = funcion_ma_bb[1]
MAD
| Métrica | Valor | Descripción | ||
|---|---|---|---|---|
| 0 | Sharpe | Cantidad | -0.054705 | Sharpe Ratio Fórmula Original |
| 1 | Drawdown | DrawDown $ (capital) | -2.793000 | Máxima pérdida flotante registrada |
| 2 | Drawup | DrawUp $ (capital) | 1.698000 | Máxima ganancia flotante registrada |
df_ma_bb = funcion_ma_bb[2]
df_ma_bb
| time | open | high | low | close | tick_volume | spread | real_volume | Operation | exposure | ... | Stoploss_final | Takeprofit_final | SL_final | TP_final | CloseOp_final | Profit_final | Date_SL_final | Date_TP_final | Profit_final_acum | Operation_final | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2018-01-02 19:45:00 | 1.20485 | 1.20495 | 1.20407 | 1.20442 | 4693 | 6 | 938600000 | Vender | 120.442 | ... | 1.228508 | 1.192376 | 1.22855 | 1.19209 | 1.19209 | 1.233 | 2018-01-15 12:15:00.000000 | 2018-01-09 13:00:00.000000 | 1.233 | Vender |
| 1 | 2018-01-03 01:00:00 | 1.20567 | 1.20614 | 1.20564 | 1.20603 | 3841 | 16 | 768200000 | Comprar | 120.603 | ... | 1.181909 | 1.218090 | 1.18169 | 1.21815 | 1.21815 | 1.212 | 2018-05-16 01:45:00.000000 | 2018-01-12 22:30:00.000000 | 2.445 | Comprar |
| 2 | 2018-01-03 06:15:00 | 1.20479 | 1.20497 | 1.20479 | 1.20495 | 1693 | 13 | 338600000 | Vender | 120.495 | ... | 1.229049 | 1.192900 | 1.22919 | 1.19278 | 1.19278 | 1.217 | 2018-01-17 02:30:00.000000 | 2018-01-09 12:30:00.000000 | 3.662 | Vender |
| 3 | 2018-01-03 10:00:00 | 1.20386 | 1.20395 | 1.20306 | 1.20318 | 6393 | 6 | 1278600000 | 0 | 0.000 | ... | 1.201206 | 1.205154 | 1.20083 | 1.20538 | 1.20083 | -0.235 | 2018-01-03 17:00:00.000000 | 2018-01-04 12:30:00.000000 | 3.427 | Comprar |
| 4 | 2018-01-03 12:15:00 | 1.20361 | 1.20367 | 1.20287 | 1.20303 | 5430 | 6 | 1086000000 | 0 | 0.000 | ... | 1.200932 | 1.205128 | 1.20083 | 1.20538 | 1.20083 | -0.220 | 2018-01-03 17:00:00.000000 | 2018-01-04 12:30:00.000000 | 3.207 | Comprar |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1003 | 2018-12-27 05:45:00 | 1.13827 | 1.13832 | 1.13804 | 1.13804 | 5668 | 15 | 850200000 | Comprar | 113.804 | ... | 1.115279 | 1.149420 | 0.00000 | 0.00000 | 0.00000 | 0.000 | 2021-11-30 00:55:25.633010 | 2021-11-30 00:55:25.633010 | 70.974 | Comprar |
| 1004 | 2018-12-27 16:45:00 | 1.14038 | 1.14355 | 1.13974 | 1.14339 | 15790 | 15 | 2368500000 | 0 | 0.000 | ... | 1.148837 | 1.137943 | 0.00000 | 0.00000 | 0.00000 | 0.000 | 2021-11-30 00:55:25.633010 | 2021-11-30 00:55:25.633010 | 70.974 | Vender |
| 1005 | 2018-12-27 19:00:00 | 1.14112 | 1.14244 | 1.14102 | 1.14227 | 14300 | 15 | 2145000000 | 0 | 0.000 | ... | 1.146450 | 1.138090 | 1.14649 | 0.00000 | 1.14649 | -0.422 | 2018-12-28 05:00:00.000000 | 2021-11-30 00:55:25.633010 | 70.552 | Vender |
| 1006 | 2018-12-28 05:00:00 | 1.14609 | 1.14650 | 1.14558 | 1.14649 | 14866 | 15 | 2229900000 | 0 | 0.000 | ... | 1.151859 | 1.141121 | 0.00000 | 0.00000 | 0.00000 | 0.000 | 2021-11-30 00:55:25.633010 | 2021-11-30 00:55:25.633010 | 70.552 | Vender |
| 1007 | 2018-12-28 18:00:00 | 1.14361 | 1.14455 | 1.14296 | 1.14417 | 30938 | 15 | 4640700000 | Vender | 114.417 | ... | 1.167053 | 1.132728 | 0.00000 | 0.00000 | 0.00000 | 0.000 | 2021-11-30 00:55:25.633010 | 2021-11-30 00:55:25.633010 | 70.552 | Vender |
987 rows × 40 columns
En dicho dataframe podemos observar una serie de columnas que fueron creadas de acuerdo a los criterios financieros citados en un inicio de este apartado, haciendo uso de los criterios estadísticos y bajo las condiciones de generación de señales de compra o venta que se citaron con anterioridad. Las primeras ocho columnas, excluyendo el index, se tratan de la base tal cual se descarga de Metatrader, posterior a estas se fueron creando paso a paso columnas que mostrarán las pautas teóricas que se mencionaron, haciendo en conjunto lo que llamamos un sistema de trading, que contenga las compras y ventas del activo en análisis así como las pérdidas o ganancias que la inversión genera.
df_ma_bb_profit= funcion_ma_bb[3]
df_ma_bb_profit
| time | Operation_final | Profit_final | Profit_final_acum | |
|---|---|---|---|---|
| 0 | 2018-01-02 19:45:00 | Vender | 1.233 | 1.233 |
| 1 | 2018-01-03 01:00:00 | Comprar | 1.212 | 2.445 |
| 2 | 2018-01-03 06:15:00 | Vender | 1.217 | 3.662 |
| 3 | 2018-01-03 10:00:00 | Comprar | -0.235 | 3.427 |
| 4 | 2018-01-03 12:15:00 | Comprar | -0.220 | 3.207 |
| ... | ... | ... | ... | ... |
| 1003 | 2018-12-27 05:45:00 | Comprar | 0.000 | 70.974 |
| 1004 | 2018-12-27 16:45:00 | Vender | 0.000 | 70.974 |
| 1005 | 2018-12-27 19:00:00 | Vender | -0.422 | 70.552 |
| 1006 | 2018-12-28 05:00:00 | Vender | 0.000 | 70.552 |
| 1007 | 2018-12-28 18:00:00 | Vender | 0.000 | 70.552 |
987 rows × 4 columns
En este dataframe visualizamos el total de operaciones que tuvo nuestro sistema de trading, mostrando el tiempo en el cual se realizaron las operaciones, así como la operación que se decidió hacer respecto a los criterios que se definieron en base al análisis técnico. Para continuar con la columna "Profit_final" que contiene los valores de las pérdidas o ganancias, según sea el caso, denotadas con el signo positivo o negativo que se obtienen de acuerdo a la asertividad de la operación realizada. Finalmente, la columna "Profit_final_acum" muestra el total acumlado de las pérdidas o ganancias de la columna de "Profit_final".
five_visualizations(df_ma_bb)
(None, None, None, None, None)
heuristic = resultados_heuristicos()
1000 0.01 0.005 20 1 198.36000000000527 1000 0.01 0.005 20 2 253.28000000000267 1000 0.01 0.005 30 1 240.9000000000039 1000 0.01 0.005 30 2 219.16999999999936 1000 0.01 0.005 40 1 113.86000000000504 1000 0.01 0.005 40 2 191.12999999999818 1000 0.02 0.01 20 1 826.6000000000054 1000 0.02 0.01 20 2 930.1900000000023 1000 0.02 0.01 30 1 921.8000000000035 1000 0.02 0.01 30 2 871.2999999999996 1000 0.02 0.01 40 1 780.750000000005 1000 0.02 0.01 40 2 908.6299999999983 2000 0.01 0.005 20 1 396.72000000001054 2000 0.01 0.005 20 2 506.56000000000535 2000 0.01 0.005 30 1 481.8000000000078 2000 0.01 0.005 30 2 438.3399999999987 2000 0.01 0.005 40 1 227.7200000000101 2000 0.01 0.005 40 2 382.25999999999635 2000 0.02 0.01 20 1 1621.7000000000082 2000 0.02 0.01 20 2 1793.6200000000051 2000 0.02 0.01 30 1 1777.6800000000064 2000 0.02 0.01 30 2 1654.8799999999997 2000 0.02 0.01 40 1 1511.1200000000072 2000 0.02 0.01 40 2 1774.1599999999971 3000 0.01 0.005 20 1 595.080000000016 3000 0.01 0.005 20 2 759.8400000000075 3000 0.01 0.005 30 1 722.7000000000113 3000 0.01 0.005 30 2 657.5099999999982 3000 0.01 0.005 40 1 341.5800000000152 3000 0.01 0.005 40 2 573.3899999999944 3000 0.02 0.01 20 1 1997.9400000000069 3000 0.02 0.01 20 2 2324.790000000002 3000 0.02 0.01 30 1 2252.1900000000046 3000 0.02 0.01 30 2 2059.9499999999957 3000 0.02 0.01 40 1 1840.5900000000086 3000 0.02 0.01 40 2 2281.3499999999935 4000 0.01 0.005 20 1 793.4400000000211 4000 0.01 0.005 20 2 1013.1200000000107 4000 0.01 0.005 30 1 963.6000000000156 4000 0.01 0.005 30 2 876.6799999999974 4000 0.01 0.005 40 1 455.4400000000202 4000 0.01 0.005 40 2 764.5199999999927 4000 0.02 0.01 20 1 2378.3600000000115 4000 0.02 0.01 20 2 2849.8800000000065 4000 0.02 0.01 30 1 2799.640000000012 4000 0.02 0.01 30 2 2465.319999999997 4000 0.02 0.01 40 1 2143.400000000012 4000 0.02 0.01 40 2 2787.4799999999946 2391.089874982834
print("El profit acumulado máximo es de: ", np.round(max(heuristic[0]), 2), "con un total de iteraciones de ", len(heuristic[0]))
El profit acumulado máximo es de: 2849.88 con un total de iteraciones de 48
PSO es un algoritmo estocástico de búsqueda basado en población, propuesto por Kennedy y Eberhart en 1995 como un modelo de las actividades sociales de insectos, pájaros y peces. Este algoritmo pretende representar el proceso natural de comunicación grupal para compartir conocimiento individual cuando grupos de animales se desplazan, migran o cazan. Si un miembro detecta un camino deseable para desplazarse, el resto de la colonia lo sigue inmediatamente. En PSO, este comportamiento animal es imitado por partículas con ciertas posiciones y velocidades en un espacio de búsqueda, donde la población es llamada swarm, y cada miembro del swarm es llamado partícula.
Cada partícula comunica las buenas posiciones a las demás y dinámicamente ajustan su propia posición y su velocidad con base en las buenas posiciones. La velocidad se ajusta con el comportamiento histórico de las partículas. De esta forma, las partículas tienden a dirigirse hacia un mejor espacio de búsqueda en el proceso de minimización de la función objetivo.
cost = PSO_Optimization(iterations=20)
2021-11-30 08:35:36,011 - pyswarms.single.global_best - INFO - Optimize for 20 iters with {'c1': 2, 'c2': 2.2, 'w': 0.73}
pyswarms.single.global_best: 0%| |0/20
7393.174512424098 0.030825897173931464 0.015412948586965732 28 1.7888124261516178
pyswarms.single.global_best: 5%|███ |1/20, best_cost=7.67e+3
7393.798430225648 0.0312466378091993 0.01562331890459965 29 1.9250272432891755
pyswarms.single.global_best: 10%|██████ |2/20, best_cost=7.67e+3
7393.95306945593 0.04130484124826865 0.020652420624134325 28 1.588373408039044
pyswarms.single.global_best: 15%|█████████▏ |3/20, best_cost=6.45e+3
7394.065956094035 0.013647329758789238 0.006823664879394619 28 1.3426161083064478
pyswarms.single.global_best: 20%|████████████▏ |4/20, best_cost=-4.1e+3
7394.148363339852 0.035457346371469266 0.017728673185734633 28 1.1632132795016528
pyswarms.single.global_best: 25%|███████████████▎ |5/20, best_cost=-4.1e+3
7394.06400518525 0.023296635854819288 0.011648317927409644 28 1.432710036837403
pyswarms.single.global_best: 30%|██████████████████▎ |6/20, best_cost=-4.1e+3
7394.007027262915 0.05191267829355727 0.025956339146778636 29 1.4420014800662122
pyswarms.single.global_best: 35%|█████████████████████▎ |7/20, best_cost=-4.1e+3
7394.003528705593 0.03857981664226928 0.01928990832113464 28 1.2371209197911528
pyswarms.single.global_best: 40%|████████████████████████▍ |8/20, best_cost=-4.1e+3
7394.118181892407 0.029897307819226566 0.014948653909613283 28 1.3267170888700297
pyswarms.single.global_best: 45%|███████████████████████████▍ |9/20, best_cost=-4.1e+3
7394.032110855378 0.05577181941839629 0.027885909709198145 29 1.410474704318567
pyswarms.single.global_best: 50%|██████████████████████████████ |10/20, best_cost=-4.1e+3
7394.024421287577 0.011924745984497373 0.0059623729922486865 27 1.334646677027867
pyswarms.single.global_best: 55%|█████████████████████████████████ |11/20, best_cost=-4.1e+3
7394.109027608227 0.026037933375703717 0.013018966687851859 28 1.2892746881884267
pyswarms.single.global_best: 60%|████████████████████████████████████ |12/20, best_cost=-4.1e+3
7394.09240722118 0.039435320830051676 0.019717660415025838 29 1.2928009480976967
pyswarms.single.global_best: 65%|███████████████████████████████████████ |13/20, best_cost=-4.1e+3
7394.026656032933 0.035510141754352645 0.017755070877176322 28 1.4110767678750131
pyswarms.single.global_best: 70%|██████████████████████████████████████████ |14/20, best_cost=-4.1e+3
7394.08625881738 0.038952333643772666 0.019476166821886333 28 1.2509233382941918
pyswarms.single.global_best: 75%|█████████████████████████████████████████████ |15/20, best_cost=-4.1e+3
7394.0827241227225 0.014892192386188392 0.007446096193094196 28 1.2223679389731927
pyswarms.single.global_best: 80%|████████████████████████████████████████████████ |16/20, best_cost=-4.1e+3
7394.047035264405 0.022121626396064208 0.011060813198032104 29 1.4201208082435153
pyswarms.single.global_best: 85%|███████████████████████████████████████████████████ |17/20, best_cost=-4.1e+3
7394.055556844873 0.02963308721062948 0.01481654360531474 28 1.4943476756263123
pyswarms.single.global_best: 90%|██████████████████████████████████████████████████████ |18/20, best_cost=-4.1e+3
7394.069886925669 0.034388624174685765 0.017194312087342883 28 1.1238600313598508
pyswarms.single.global_best: 95%|█████████████████████████████████████████████████████████ |19/20, best_cost=-4.1e+3
7394.076077868449 0.029634604196419827 0.014817302098209913 28 1.4579229269757799
pyswarms.single.global_best: 100%|████████████████████████████████████████████████████████████|20/20, best_cost=-4.1e+3 2021-11-30 08:53:22,655 - pyswarms.single.global_best - INFO - Optimization finished | best cost: -4095.721014399602, best pos: [7.39406596e+03 1.36473298e-02 2.86088245e+01 1.34261611e+00]
1066.7128760814667
print("El profit acumulado máximo es de: ", np.round(cost[0], 2), "con un total de iteraciones de ", 20)
El profit acumulado máximo es de: 4095.72 con un total de iteraciones de 20
funcion_ma_bb_opt = function(cost[1][0],cost[1][1],cost[1][2],cost[1][3], 'backtest')
7394.065956094035 0.013647329758789238 0.006823664879394619 28 1.3426161083064478
MAD_opt = funcion_ma_bb_opt[1]
MAD_opt
| Métrica | Valor | Descripción | ||
|---|---|---|---|---|
| 0 | Sharpe | Cantidad | -0.025424 | Sharpe Ratio Fórmula Original |
| 1 | Drawdown | DrawDown $ (capital) | -154.979622 | Máxima pérdida flotante registrada |
| 2 | Drawup | DrawUp $ (capital) | 86.880275 | Máxima ganancia flotante registrada |
df_ma_bb_opt = funcion_ma_bb_opt[2]
df_ma_bb_opt
| time | open | high | low | close | tick_volume | spread | real_volume | Operation | exposure | ... | Stoploss_final | Takeprofit_final | SL_final | TP_final | CloseOp_final | Profit_final | Date_SL_final | Date_TP_final | Profit_final_acum | Operation_final | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2018-01-02 07:30:00 | 1.20178 | 1.20201 | 1.20174 | 1.20199 | 2359 | 9 | 471800000 | 0 | 0.000000 | ... | 1.202529 | 1.201451 | 1.20279 | 1.20145 | 1.20279 | -5.915253 | 2018-01-02 08:00:00.000000 | 2018-01-03 13:45:00.000000 | -5.915253 | Vender |
| 1 | 2018-01-02 16:45:00 | 1.20461 | 1.20476 | 1.20347 | 1.20383 | 7169 | 6 | 1433800000 | 0 | 0.000000 | ... | 1.201966 | 1.205694 | 1.20164 | 1.20584 | 1.20584 | 14.862073 | 2018-01-03 12:30:00.000000 | 2018-01-02 22:45:00.000000 | 8.946820 | Comprar |
| 2 | 2018-01-02 19:45:00 | 1.20485 | 1.20495 | 1.20407 | 1.20442 | 4693 | 6 | 938600000 | Vender | 8905.560919 | ... | 1.220857 | 1.196201 | 1.22096 | 1.19618 | 1.19618 | 60.927103 | 2018-01-15 06:30:00.000000 | 2018-01-08 17:00:00.000000 | 69.873923 | Vender |
| 3 | 2018-01-02 22:30:00 | 1.20538 | 1.20569 | 1.20530 | 1.20568 | 2677 | 16 | 535400000 | 0 | 0.000000 | ... | 1.206688 | 1.204672 | 1.20699 | 1.20428 | 1.20428 | 10.351692 | 2018-01-04 14:45:00.000000 | 2018-01-03 04:15:00.000000 | 80.225616 | Vender |
| 5 | 2018-01-03 03:30:00 | 1.20544 | 1.20563 | 1.20452 | 1.20473 | 3867 | 13 | 773400000 | 0 | 0.000000 | ... | 1.203902 | 1.205558 | 1.20370 | 1.20580 | 1.20580 | 7.911651 | 2018-01-03 09:30:00.000000 | 2018-01-03 07:30:00.000000 | 88.137266 | Comprar |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1923 | 2018-12-17 13:45:00 | 1.13365 | 1.13507 | 1.13353 | 1.13497 | 11042 | 15 | 1656300000 | 0 | 0.000000 | ... | 1.137720 | 1.132220 | 1.13788 | 0.00000 | 1.13788 | -21.516732 | 2018-12-18 12:00:00.000000 | 2021-11-30 09:08:28.257190 | 4083.003221 | Vender |
| 1924 | 2018-12-17 19:15:00 | 1.13392 | 1.13482 | 1.13388 | 1.13470 | 10654 | 15 | 1598100000 | 0 | 0.000000 | ... | 1.135350 | 1.134050 | 1.13551 | 1.13383 | 1.13551 | -5.989193 | 2018-12-17 20:00:00.000000 | 2018-12-18 08:45:00.000000 | 4077.014028 | Vender |
| 1925 | 2018-12-18 03:30:00 | 1.13494 | 1.13590 | 1.13480 | 1.13581 | 8882 | 15 | 1332300000 | 0 | 0.000000 | ... | 1.136757 | 1.134863 | 1.13692 | 1.13467 | 1.13467 | 8.429235 | 2018-12-18 10:15:00.000000 | 2018-12-18 06:45:00.000000 | 4085.443263 | Vender |
| 1926 | 2018-12-18 07:00:00 | 1.13467 | 1.13476 | 1.13431 | 1.13433 | 6292 | 15 | 943800000 | 0 | 0.000000 | ... | 1.133594 | 1.135066 | 0.00000 | 1.13572 | 1.13572 | 10.277752 | 2021-11-30 09:08:28.257190 | 2018-12-18 09:45:00.000000 | 4095.721014 | Comprar |
| 1927 | 2018-12-18 08:45:00 | 1.13420 | 1.13424 | 1.13378 | 1.13383 | 5627 | 15 | 844050000 | Vender | 8383.613803 | ... | 1.149304 | 1.126093 | 0.00000 | 0.00000 | 0.00000 | 0.000000 | 2021-11-30 09:08:28.257190 | 2021-11-30 09:08:28.257190 | 4095.721014 | Vender |
1897 rows × 40 columns
df_ma_bb_profit_opt= funcion_ma_bb_opt[3]
df_ma_bb_profit_opt
| time | Operation_final | Profit_final | Profit_final_acum | |
|---|---|---|---|---|
| 0 | 2018-01-02 07:30:00 | Vender | -5.915253 | -5.915253 |
| 1 | 2018-01-02 16:45:00 | Comprar | 14.862073 | 8.946820 |
| 2 | 2018-01-02 19:45:00 | Vender | 60.927103 | 69.873923 |
| 3 | 2018-01-02 22:30:00 | Vender | 10.351692 | 80.225616 |
| 5 | 2018-01-03 03:30:00 | Comprar | 7.911651 | 88.137266 |
| ... | ... | ... | ... | ... |
| 1923 | 2018-12-17 13:45:00 | Vender | -21.516732 | 4083.003221 |
| 1924 | 2018-12-17 19:15:00 | Vender | -5.989193 | 4077.014028 |
| 1925 | 2018-12-18 03:30:00 | Vender | 8.429235 | 4085.443263 |
| 1926 | 2018-12-18 07:00:00 | Comprar | 10.277752 | 4095.721014 |
| 1927 | 2018-12-18 08:45:00 | Vender | 0.000000 | 4095.721014 |
1897 rows × 4 columns
five_visualizations(df_ma_bb_opt)
(None, None, None, None, None)
Al hacer uso de los datos óptimos obtenidos en el periodo de prueba, se procede a realizar el mismo análisis para demostrar la efectividad de la optimización realizada.
funcion_ma_bb_prueba = function(cost[1][0],cost[1][1],cost[1][2],cost[1][3], 'prueba')
7394.065956094035 0.013647329758789238 0.006823664879394619 28 1.3426161083064478
MAD_prueba= funcion_ma_bb_prueba[1]
MAD_prueba
| Métrica | Valor | Descripción | ||
|---|---|---|---|---|
| 0 | Sharpe | Cantidad | -0.079211 | Sharpe Ratio Fórmula Original |
| 1 | Drawdown | DrawDown $ (capital) | -137.085983 | Máxima pérdida flotante registrada |
| 2 | Drawup | DrawUp $ (capital) | 85.845106 | Máxima ganancia flotante registrada |
df_ma_bb_prueba= funcion_ma_bb_prueba[2]
df_ma_bb_prueba
| time | open | high | low | close | tick_volume | spread | real_volume | Operation | exposure | ... | Stoploss_final | Takeprofit_final | SL_final | TP_final | CloseOp_final | Profit_final | Date_SL_final | Date_TP_final | Profit_final_acum | Operation_final | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2019-01-02 13:00:00 | 1.14362 | 1.14383 | 1.14248 | 1.14250 | 11138 | 15 | 1670700000 | 0 | 0.000000 | ... | 1.139361 | 1.145639 | 1.13803 | 1.14569 | 1.13803 | -33.051475 | 2019-01-02 15:15:00.000000 | 2019-01-07 15:45:00.000000 | -33.051475 | Comprar |
| 1 | 2019-01-02 19:30:00 | 1.13464 | 1.13502 | 1.13328 | 1.13358 | 12202 | 15 | 1830300000 | 0 | 0.000000 | ... | 1.129031 | 1.138129 | 1.12860 | 1.13818 | 1.13818 | 34.012703 | 2019-02-11 16:15:00.000000 | 2019-01-03 11:30:00.000000 | 0.961229 | Comprar |
| 2 | 2019-01-03 00:30:00 | 1.13324 | 1.13355 | 1.13093 | 1.13219 | 8254 | 16 | 1238100000 | 0 | 0.000000 | ... | 1.130301 | 1.134079 | 1.13014 | 1.13446 | 1.13446 | 16.784530 | 2019-01-24 19:15:00.000000 | 2019-01-03 01:00:00.000000 | 17.745758 | Comprar |
| 3 | 2019-01-03 04:15:00 | 1.13473 | 1.13546 | 1.13453 | 1.13543 | 5428 | 15 | 814200000 | 0 | 0.000000 | ... | 1.136804 | 1.134056 | 1.13682 | 1.13401 | 1.13682 | -10.277752 | 2019-01-03 05:30:00.000000 | 2019-01-24 12:15:00.000000 | 7.468007 | Vender |
| 4 | 2019-01-03 05:15:00 | 1.13611 | 1.13692 | 1.13605 | 1.13677 | 7223 | 15 | 1083450000 | Comprar | 8405.352357 | ... | 1.121256 | 1.144527 | 1.12113 | 1.14511 | 1.14511 | 61.666510 | 2019-03-07 19:00:00.000000 | 2019-01-07 15:15:00.000000 | 69.134517 | Comprar |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1974 | 2019-12-16 06:45:00 | 1.11304 | 1.11322 | 1.11298 | 1.11320 | 2332 | 15 | 349800000 | 0 | 0.000000 | ... | 1.113650 | 1.112750 | 1.11371 | 1.11251 | 1.11371 | -3.770974 | 2019-12-16 08:15:00.000000 | 2019-12-18 13:15:00.000000 | 5171.631552 | Vender |
| 1975 | 2019-12-16 10:15:00 | 1.11398 | 1.11455 | 1.11335 | 1.11434 | 9119 | 15 | 1367850000 | 0 | 0.000000 | ... | 1.115204 | 1.113476 | 1.11528 | 1.11305 | 1.11305 | 9.538345 | 2019-12-16 15:45:00.000000 | 2019-12-16 10:45:00.000000 | 5181.169897 | Vender |
| 1976 | 2019-12-16 15:30:00 | 1.11438 | 1.11483 | 1.11429 | 1.11478 | 7209 | 15 | 1081350000 | 0 | 0.000000 | ... | 1.115529 | 1.114031 | 1.11555 | 1.11359 | 1.11359 | 8.798938 | 2019-12-17 12:00:00.000000 | 2019-12-16 17:45:00.000000 | 5189.968835 | Vender |
| 1977 | 2019-12-17 00:45:00 | 1.11445 | 1.11449 | 1.11374 | 1.11381 | 5734 | 15 | 860100000 | 0 | 0.000000 | ... | 1.113319 | 1.114301 | 1.11319 | 1.11435 | 1.11435 | 3.992796 | 2019-12-17 10:15:00.000000 | 2019-12-17 04:45:00.000000 | 5193.961631 | Comprar |
| 1978 | 2019-12-17 01:15:00 | 1.11388 | 1.11402 | 1.11377 | 1.11398 | 2395 | 15 | 359250000 | Vender | 8236.841594 | ... | 1.129183 | 1.106379 | 0.00000 | 0.00000 | 0.00000 | 0.000000 | 2021-11-30 09:09:48.764510 | 2021-11-30 09:09:48.764510 | 5193.961631 | Vender |
1952 rows × 40 columns
df_ma_bb_profit_prueba = funcion_ma_bb_prueba[3]
df_ma_bb_profit_prueba
| time | Operation_final | Profit_final | Profit_final_acum | |
|---|---|---|---|---|
| 0 | 2019-01-02 13:00:00 | Comprar | -33.051475 | -33.051475 |
| 1 | 2019-01-02 19:30:00 | Comprar | 34.012703 | 0.961229 |
| 2 | 2019-01-03 00:30:00 | Comprar | 16.784530 | 17.745758 |
| 3 | 2019-01-03 04:15:00 | Vender | -10.277752 | 7.468007 |
| 4 | 2019-01-03 05:15:00 | Comprar | 61.666510 | 69.134517 |
| ... | ... | ... | ... | ... |
| 1974 | 2019-12-16 06:45:00 | Vender | -3.770974 | 5171.631552 |
| 1975 | 2019-12-16 10:15:00 | Vender | 9.538345 | 5181.169897 |
| 1976 | 2019-12-16 15:30:00 | Vender | 8.798938 | 5189.968835 |
| 1977 | 2019-12-17 00:45:00 | Comprar | 3.992796 | 5193.961631 |
| 1978 | 2019-12-17 01:15:00 | Vender | 0.000000 | 5193.961631 |
1952 rows × 4 columns
five_visualizations(df_ma_bb_prueba)
(None, None, None, None, None)
Para el presente proyecto podemos concluir la importancia de hacer diversas pruebas para poder corroborar los resultados que se obtengan, asimismo que la creación de un sistema de trading es todo un reto que conlleva diversos conocimientos, no solo de programación y finanzas sino de introspección misma de acuerdo a los alcances del inversionista. Puesto que de acuerdo a los intereses que este tenga serán los alcances a los que se lleguen. Por otro lado, el reconocimiento de ello hace que se caigan las mínimas veces en un sesgo.
En este caso se presentaron dos periodos, uno de backtesting y uno de prueba con ellos se pudieron corroborar los resultados que se obtenieron en el entrenamiento con los valores óptimos que proceden de dos optimizaciones por parte de una búsqueda exhaustiva y de PSO. Finalmente, se nota que los resultados convienen bastante debido a que el profit acumulado crece llegando a valores altos, que era el objetivo del este proyecto.
En conclusión, cabe destacar la importancia de asentar bien las bases de las transacciones de trading bajo la condición establecida, que en este caso fue la maximización del profit, para visualizar los alcances que tuvo la o las inversiones realizadas.
[1] Avatrade, (n.d). "Bandas de Bollinger". Recuperado de: https://www.avatrade.es/educacion/trading-para-principiantes/bandas-de-bollinger. El día 28 de noviembre de 2021.
[2] Wikipedia, (2020). "Eurodólar". Recuperado de: https://es.wikipedia.org/wiki/Eurodólar. El día 28 de noviembre de 2021.
[3] Canessa Raúl, (n.d). "Las Medias Móviles – Definición y uso en el trading". Recuperado de: https://www.tecnicasdetrading.com/2010/06/medias-moviles.html. El día 28 de noviembre de 2021.